package org.utils.lang;

public class ClassUtils
{
	private ClassUtils() {}
	
	public static String getClassName(Object obj)
	{
		return getClassName(obj.getClass());
	}
	
	public static String getClassName(Class c)
	{
		String name = c.getName();
		int pos = name.lastIndexOf('.');
		return name.substring(pos+1);
	}

	public static Object newInstance(Class c, Object arg)
		throws ReflectionException
	{
	    try
	    {
			Class[] cTypes = { arg.getClass() };
			Object[] params = { arg };
			return c.getConstructor(cTypes).newInstance(params);
	    }
	    catch (Exception e)
	    {
	    	throw new ReflectionException(e);
	    }
	}

	public static Object newInstance(Class c, Object arg1, Object arg2)
		throws ReflectionException
	{
	    try
	    {
			Class[] cTypes = { arg1.getClass(), arg2.getClass() };
			Object[] params = { arg1, arg2 };
			return c.getConstructor(cTypes).newInstance(params);
	    }
	    catch (Exception e)
	    {
	    	throw new ReflectionException(e);
	    }
	}

	public static Object newInstance(Class c, Object[] params)
		throws ReflectionException
	{
	    try
		{
			Class[] cTypes = new Class[params.length];
			for (int i = 0; i < params.length; i++)
			{
				cTypes[i] = params[i].getClass();
			}
			return c.getConstructor(cTypes).newInstance(params);
	    }
	    catch (Exception e)
	    {
	    	throw new ReflectionException(e);
	    }
	}

	public static Object invoke(Object obj, String name)
		throws ReflectionException
	{
	    try
	    {
			return obj.getClass().getMethod(name, (Class[])null).invoke(obj, (Object[])null);
	    }
	    catch (Exception e)
	    {
	    	throw new ReflectionException(e);
	    }
	}

	public static Object invoke(Object obj, String name, Object arg)
		throws ReflectionException
	{
	    try
	    {
			Class[] cTypes = { arg.getClass() };
			Object[] params = { arg };
			return obj.getClass().getMethod(name, cTypes).invoke(obj, params);
	    }
	    catch (Exception e)
	    {
	    	throw new ReflectionException(e);
	    }
	}

	public static Object invoke(Object obj, String name, Class to, Object arg)
		throws ReflectionException
	{
	    try
	    {
			Class[] cTypes = { to };
			Object[] params = { arg };
			return obj.getClass().getMethod(name, cTypes).invoke(obj, params);
	    }
	    catch (Exception e)
	    {
	    	throw new ReflectionException(e);
	    }
	}

	public static Object invoke(Object obj, String name, Object arg1, Object arg2)
		throws ReflectionException
	{
	    try
	    {
			Class[] cTypes = { arg1.getClass(), arg2.getClass() };
			Object[] params = { arg1, arg2 };
			return obj.getClass().getMethod(name, cTypes).invoke(obj, params);
	    }
	    catch (Exception e)
	    {
	    	throw new ReflectionException(e);
	    }
	}

	public static Object invoke(Object obj, String name, Object[] params)
		throws ReflectionException
	{
	    try
	    {
			Class[] cTypes = new Class[params.length];
			for (int i = 0; i < params.length; i++)
			{
				cTypes[i] = params[i].getClass();
			}
			return obj.getClass().getMethod(name, cTypes).invoke(obj, params);
	    }
	    catch (Exception e)
	    {
	    	throw new ReflectionException(e);
	    }
	}
}
